package com.gxp.controller;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Properties;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetails;
import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.support.RequestContextUtils;

import com.gxp.pojo.Role;
import com.gxp.pojo.User;
import com.gxp.service.SiteSettingService;
import com.gxp.service.UserService;
import com.gxp.util.common.GXPConstant;
import com.gxp.util.security.Des;

@Controller
public class RegisterController {
	
	Logger logger = Logger.getLogger(RegisterController.class);

	@Autowired
	private UserService userService;
	
	@Autowired
	private SiteSettingService siteService;
	
	@Autowired
    @Qualifier("org.springframework.security.authenticationManager")
    protected AuthenticationManager authenticationManager;

	
	@RequestMapping(value="/register/user/create",method=RequestMethod.POST)
	public ModelAndView saveUser(HttpServletRequest request, User userInput) {
		System.out.println("Save User controller is registerUser invoked.........");

		// construct User entity
		// encrypt password
		String plaintPassword = request.getParameter("password");
		userInput.setPassword(plaintPassword);
		System.out.println("plaint password: " + plaintPassword);
		String encryptedPassword = Des.encryptUserPassord(userInput.getUserId(), userInput.getPassword());
		userInput.setPassword(encryptedPassword);		
		userInput.setRegDate(new Date());		

		// default assign role as: ROLE_BUYER
		Role role = new Role();
		role.setRoleId(Integer.valueOf(GXPConstant.ROLE_BUYER));
		List<Role> roleList = userInput.getRoleList();
		if (roleList == null) {
			roleList = new ArrayList<Role>();
		}
		roleList.add(role);
		userInput.setRoleList(roleList);
		
		// insert into user_master and user_role_user table
		userService.insertUser(userInput);
		
		UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(
				userInput.getUserId(), plaintPassword);
		ModelAndView mav = new ModelAndView();
		 try{
		        token.setDetails(new WebAuthenticationDetails(request));
		        Authentication authenticatedUser = authenticationManager
		                .authenticate(token);

		        SecurityContextHolder.getContext().setAuthentication(authenticatedUser);
		        request.getSession().setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, SecurityContextHolder.getContext());
		        }
		        catch( AuthenticationException e ){
		            System.out.println("Authentication failed: " + e.getMessage());
		            mav.setViewName("/");
		            return mav;
		}
		 
		 
		 mav.setViewName("/public/registrySuccess");
		 return mav;
	}
	
	@RequestMapping(value="/register",method=RequestMethod.GET)
	@ResponseBody
	public ModelAndView registerUser() {
		ModelAndView mav = new ModelAndView();
		mav.setViewName("/public/registry");
		return mav;
	}
	
	@RequestMapping(value="/public/user/checkuserid",method=RequestMethod.POST)
	@ResponseBody
	public boolean checkUserId(String userId, Integer getBackPwd) {
		logger.debug("RegisterController checkUserId is invoked.........");
		logger.debug("user id : " + userId);
		logger.debug("getBackPwd" + getBackPwd);
		String userName = userService.checkUserId(userId);
		if (getBackPwd != null && getBackPwd.intValue() == 1) {
			return userName == null ? false : true;
		} else {			
			return userName == null ? true : false;
		}		
	}
	
	@RequestMapping(value="/public/user/checkusermail",method=RequestMethod.POST)
	@ResponseBody
	public boolean checkUserMail(String email, Integer getBackPwd, String userId) {
		logger.debug("RegisterController checkUserMail is invoked.........");
		if (getBackPwd != null && getBackPwd.intValue() == 1) {
			if (!StringUtils.hasText(userId)) {
				return false;
			}
			User user = userService.getActiveUser(userId);
			if (user != null && email.equalsIgnoreCase(user.getEmail())) {
				return true;
			} else {
				return false;
			}
		} else {
			String dbUserId = userService.checkUserMail(email);
			if (dbUserId == null || dbUserId.equals(userId)) {
				return true;
			} else {
				return false;
			}
		}
		
	}
	
	
	@RequestMapping(value="/public/user/checkcode",method=RequestMethod.POST)
	@ResponseBody
	public boolean checkCodeNumber(String checkcode, HttpServletRequest request) {
		String sessionCode = (String) request.getSession().getAttribute(
				com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY);
		logger.debug("input check code: " + checkcode);
		logger.debug("session check code: " + sessionCode);
		if (checkcode != null && checkcode.equalsIgnoreCase(sessionCode)) {
			return true;
		}
		return false;
	}
	
	@RequestMapping(value="/public/getBackPwd",method=RequestMethod.POST)
	@ResponseBody
	public String sendUserNewPwd(User user, HttpServletRequest request, HttpServletResponse response) {
		logger.debug("****************************>sendUserNewPwd");
		
		// generate passcode
		String newPwd = Des.getRadomPwd(8);		
		String encryptedPassword = Des.encryptUserPassord(user.getUserId(), newPwd);
		user.setPassword(encryptedPassword);
		userService.updateUserPassword(user);
		// Get user email address
		User existingUser = userService.getActiveUser(user.getUserId());
        String userEmail = existingUser.getEmail();
        // Get site email setting
        String siteEmail = siteService.getSiteSettingByKey(GXPConstant.SITE_SETTING_KEY_EMAIL);
        String siteEmailPassword = siteService.getSiteSettingByKey(GXPConstant.SITE_SETTING_KEY_EMAIL_PASSWORD);
        String siteEmailServer = siteService.getSiteSettingByKey(GXPConstant.SITE_SETTING_KEY_EMAIL_SERVER);
        
        // Create properties for email sending
        Properties props = new Properties(); 
        props.put("mail.debug", "true");
        props.put("mail.smtp.starttls.enable", "false");
        props.put("mail.smtp.auth", "true");
        // Get email session
        Session session = Session.getInstance(props);
        try {
        	
        	ApplicationContext ctx = RequestContextUtils.getWebApplicationContext(request);
    		
            // Instantiate a message
            Message msg = new MimeMessage(session);
            //Set message attributes
            msg.setFrom(new InternetAddress(siteEmail));
            InternetAddress[] address = {new InternetAddress(userEmail)};
            msg.setRecipients(Message.RecipientType.TO, address);
            String subject = ctx.getMessage("Label.common.getback.mail.subject", null, RequestContextUtils.getLocale(request));
            msg.setSubject(subject);
            msg.setSentDate(new Date());
            // Set message content
            String content = ctx.getMessage("Label.common.getback.mail.content", null, RequestContextUtils.getLocale(request));
            msg.setText(user.getUserId() + "  " + content + "\n" + newPwd); 
            
            // Send out message
			Transport t = session.getTransport("smtp");
			try {
				t.connect(siteEmailServer, siteEmail, Des.decrypt(siteEmailPassword));
				t.sendMessage(msg, msg.getAllRecipients());
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} finally {
				t.close();
			}
        } catch (MessagingException mex) {
            mex.printStackTrace();
        }
		
		return "success";
	}
	
	
	
	
	@RequestMapping(value="/public/forgetPassword",method=RequestMethod.GET)
	public ModelAndView handleGetBackPwd(HttpServletRequest request) {
		
		ModelAndView mav = new ModelAndView();
		mav.setViewName("/forgetPassword");
		return mav;		
	}
}
